Largest perimeter triangle¶
Time: O(NLogN); Space: O(1); easy
Given an array A of positive lengths, return the largest perimeter of a triangle with non-zero area, formed from 3 of these lengths.
If it is impossible to form any triangle of non-zero area, return 0.
Example 1:
Input: A = [2,1,2]
Output: 5
Example 2:
Input: A = [1,2,1]
Output: 0
Example 3:
Input: A = [3,2,3,4]
Output: 10
Example 4:
Input: A = [3,6,2,3]
Output: 8
Constraints:
3 <= len(A) <= 10000
1 <= A[i] <= 10^6
1. Sort¶
Intuition
Without loss of generality, say the sidelengths of the triangle are a <= b <= c. The necessary and sufficient condition for these lengths to form a triangle of non-zero area is a + b > c.
Say we knew cc already. There is no reason not to choose the largest possible aa and bb from the array. If a + b > >c, then it forms a triangle, otherwise it doesn’t.
Algorithm
This leads to a simple algorithm: Sort the array. For any cc in the array, we choose the largest possible a <= b <= c: these are just the two values adjacent to c. If this forms a triangle, we return the answer.
[1]:
class Solution1(object):
"""
Time: O(NLogN), where N is the length of A.
Space: O(1).
"""
def largestPerimeter(self, A) -> int:
"""
:type A: List[int]
:rtype: int
"""
A.sort()
# for i in reversed(range(len(A) - 2)):
for i in range(len(A) - 3, -1, -1):
if A[i] + A[i+1] > A[i+2]:
return A[i] + A[i+1] + A[i+2]
return 0
[2]:
s = Solution1()
A = [2,1,2]
assert s.largestPerimeter(A) == 5
A = [1,2,1]
assert s.largestPerimeter(A) == 0
A = [3,2,3,4]
assert s.largestPerimeter(A) == 10
A = [3,6,2,3]
assert s.largestPerimeter(A) == 8